package com.example.demo.zaqizabatest;

import java.math.BigInteger;

/**
 * @ClassName FactorialQuestion
 * @Author lys4134
 * @Date 2021/08/20 16:42:45
 * @Description FactorialQuestion
 * @Version 1.0
 **/
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
public class 阶乘问题 {

    private static int multiply(int n, int result) {
        if (n == 1) {
            return result;
        }
        return multiply(n-1, result*n);
    }

    private static final BigInteger ONE = BigInteger.ONE;

    private static int multiply1(int n) {
        if (n == 1) {
            return 1;
        }
        return n*(multiply1(n- 1));
    }

    private static BigInteger multiplyByBigInteger(int n) {
        BigInteger a = BigInteger.valueOf(n);
        BigInteger b = BigInteger.ONE;
        BigInteger s = BigInteger.ONE;
        for (BigInteger i = BigInteger.ONE; i.compareTo(a) <= 0; i = i.add(b)) {
            s = s.multiply(i);
        }
        return s;
    }

    public static void main(String[] args) {
        System.out.println(multiplyByBigInteger(10000));
        System.out.println(JieCheng(1000));
//        long a = System.currentTimeMillis();
//        System.out.println(multiply(BigInteger.valueOf(50), BigInteger.valueOf(1)));
//        long b = System.currentTimeMillis();
//        System.out.println(multiply1(BigInteger.valueOf(50)));
//        long c = System.currentTimeMillis();
//        System.out.println(b-a);System.out.println(c-b);
    }



    public static String JieCheng(int x) {
        int[] list = new int[10000];  //创建一个数组用来存放计算得到的整数
        list[0] = 1;  //给初值
        int listLength = 1; //标记数组当前的长度
        int midum1 = 0;  //该参数用来标定每次进位的数字 需要每次清零
        for (int i = 2; i <= x; i++) {  //对阶乘的数字进行循环相乘，从2开始
            for (int j = 0; j < listLength; j++) {  //对当前的数组进行遍历并与当前的i相乘
                int midum = list[j] * i + midum1; //相乘结果加上进位
                midum1 = 0;  //进位清零 目的是为了保证在对进位判断时均为当前进位
                if (midum > 9) {  //若大于9 则将该数拆分为个位数字与进位
                    list[j] = midum % 10;
                    midum1 = midum / 10;
                } else {  //小于9直接送入数组
                    list[j] = midum;
                }
            }
            //将当前进位一个个的存放进数组
            if (midum1 > 0) {
                while (midum1 > 0) {
                    list[listLength++] = midum1 % 10;
                    midum1 /= 10;
                }
            }
        }

        String s = "";
        for (int i = 0; i < listLength; i++) {
            s = s + list[i];//拼接成字符串，最终放在变量s中
        }
        s = new StringBuffer(s).reverse().toString(); //字符串逆置
        return s;
    }

}
